package com.loe.ktui.ui

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.text.TextUtils.TruncateAt
import android.util.AttributeSet
import android.util.TypedValue
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.isVisible
import com.loe.ktui.*
import com.loe.ktui.addTextAfterListener
import com.loe.ktui.util.KtColor
import com.loe.ktui.util.UiShape

open class UiText(id: String? = null) : UiView(id)
{
    companion object
    {
        const val TEXT_BOLD = "bold"
        const val TEXT_DELETE = "delete"
        const val TEXT_UNDER = "under"
        const val TEXT_NORMAL = "normal"
    }

    open var text: String? = null
    open var textColor: Int? = null
    open var hint: String? = null
    open var hintColor: Int? = null
    open var gravity: Int? = null
    open var isTextSelectable: Boolean? = null
    open var minLines: Int? = null
    open var maxLines: Int? = null
    open var ellipsis: TruncateAt? = null
    open var bold: Boolean? = null
    open var italic: Boolean? = null
    open var textStyle: String? = null
    open var textSize: Any? = null
    open var autoVisible: Boolean? = null
    open var image: Any? = null
    open var imageTop: Any? = null
    open var imageWidth: Any? = null
    open var imageHeight: Any? = null
    open var imagePadding: Any? = null
    open var imageColor: Int? = null
    open var imageDirect: String? = null

    open var onText: (KtTextView.(s: String) -> Unit)? = null
    open fun onText(onText: KtTextView.(s: String) -> Unit)
    {
        this.onText = onText
    }

    open fun initUI(context: Context, view: KtTextView)
    {
        super.initUI(context, view)

        isClick?.let { view.setClick(it) }

        text?.let { view.setAutoText(it) }
        view.setTextColor(textColor ?: KtColor.text)
        hint?.let { view.hint = it }
        hintColor?.let { view.setHintTextColor(it) }
        gravity?.let { view.gravity = it }
        isTextSelectable?.let { view.setTextIsSelectable(it) }
        minLines?.let { view.minLines = it }
        maxLines?.let { view.maxLines = it }
        ellipsis?.let { view.ellipsize = it }
        bold?.let { view.setBold(it) }
        italic?.let { view.setItalic(it) }
        textStyle?.let { view.setTextStyle(it) }
        hintColor?.let { view.setHintTextColor(it) }
        textSize?.let { view.setTextSize(TypedValue.COMPLEX_UNIT_PX, it.distFloat) }
        autoVisible?.let { view.isAutoVisible = it }
        image?.let()
        {
            view.image = it
            view.imageTop = imageTop.dist
            view.imageWidth = (imageWidth ?: 14).dist
            view.imageHeight = (imageHeight ?: 14).dist
            view.imagePadding = (imagePadding ?: 4).dist
            view.imageColor = imageColor ?: 0
            view.imageDirect = imageDirect ?: ""
            view.notifyImage()
        }

        onText?.let { onText -> view.setTextListener{ view.onText(it) } }
    }

    /** 创建view */
    override fun createView(context: Context, parent: ViewGroup?): KtTextView
    {
        return KtTextView(context).also()
        {
            initUI(context, it)
            addToParent(parent, it)
        }
    }
}

fun Any.ui_Text(id: String? = null, block: (UiText.() -> Unit)? = null): UiText
{
    val ui = UiText(id)
    block?.let { ui.it() }
    if (this is UiGroup) addChild(ui)
    return ui
}

@SuppressLint("AppCompatCustomView")
open class KtTextView : TextView
{
    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        initXML(attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        initXML(attrs)
    }

    private fun initXML(attrs: AttributeSet)
    {
    }

    /******************************************* 图片 *******************************************/

    var image: Any? = null
    var imageTop = 0
    var imageWidth = 0
    var imageHeight = 0
    var imagePadding = 0
    var imageColor = 0
    var imageDirect = ""

    fun notifyImage()
    {
        if (image is UiShape)
        {
            setImage((image as UiShape).createDrawable())
        } else
        {
            context.getUrlDrawable(image.toString()) { setImage(it) }
        }
    }

    fun setImage(it: Drawable)
    {
        it.setBounds(0, imageTop, imageWidth, imageHeight + imageTop)
        if (imageColor != 0)
        {
            it.colorFilter = PorterDuffColorFilter(imageColor, PorterDuff.Mode.SRC_ATOP)
        }
        val ds = compoundDrawables
        when (imageDirect)
        {
            "top" -> ds[1] = it
            "right" -> ds[2] = it
            "bottom" -> ds[3] = it
            else -> ds[0] = it
        }
        setCompoundDrawables(ds[0], ds[1], ds[2], ds[3])
        compoundDrawablePadding = imagePadding
    }

    /******************************************* 其他 *******************************************/

    var isAutoVisible: Boolean = false

    fun setAutoText(s: String?)
    {
        if (isAutoVisible) isVisible = s == null || s.trim().isEmpty()
        text = s
    }

    fun setClick(isClick: Boolean)
    {
        isAlpha = isClick
        isClickable = isClick
    }

    private var isAlpha = false

    override fun setTextColor(color: Int)
    {
        if (isAlpha)
        {
            val states = arrayOfNulls<IntArray>(3)
            states[0] = intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_pressed)
            states[1] = intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed)
            states[2] = intArrayOf(-android.R.attr.state_enabled)
            val alphaColor = (0xbb shl 24) + (color and 0xFFFFFF)
            setTextColor(ColorStateList(states, intArrayOf(color, alphaColor, alphaColor)))
        } else
        {
            super.setTextColor(color)
        }
    }

    private var onText: ((s: String) -> Unit)? = null

    private val addTextChanged by lazy {
        addTextAfterListener()
        {
            onText?.invoke(it)
        }
    }

    fun setTextListener(onText: (s: String) -> Unit)
    {
        this.onText = onText
        addTextChanged
    }

    /***************************************** 文本样式 ***************************************/

    fun setBold(bold: Boolean)
    {
        typeface = if (bold) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
    }

    fun setItalic(italic: Boolean)
    {
        setTypeface(Typeface.DEFAULT, if (italic) Typeface.ITALIC else Typeface.NORMAL)
    }

    fun setTextStyle(textStyle: String)
    {
        when (textStyle)
        {
            "bold" -> paint.flags = Paint.FAKE_BOLD_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
            "delete" -> paint.flags = Paint.STRIKE_THRU_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
            "under" -> paint.flags = Paint.UNDERLINE_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
            // normal
            else -> paint.flags = Paint.ANTI_ALIAS_FLAG
        }
    }

    fun setTextSize(size: Any)
    {
        if (size is Double)
        {
            setTextSize(TypedValue.COMPLEX_UNIT_DIP, size.toFloat())
        } else
        {
            setTextSize(TypedValue.COMPLEX_UNIT_PX, size.toString().toFloat())
        }
    }
}